/*
 * Copyright 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.j2cl.jre.java.lang;

import static com.google.j2cl.jre.testing.TestUtils.isWasm;

import junit.framework.TestCase;

/** Tests for the JRE Boolean type. */
public class BooleanTest extends TestCase {

  static volatile boolean bfalse = false;
  static volatile boolean btrue = true;

  static volatile String false1 = "t";
  static volatile String false2 = "1";
  static volatile String false3 = "false";
  static volatile String false4 = null;
  static volatile String true1 = "true";
  static volatile String true2 = "TRUE";
  static volatile String true3 = "TrUe";

  public void testCompare() {
    assertTrue("Boolean.compare failed for false < true", Boolean.compare(false, true) < 0);
    assertTrue("Boolean.compare failed for true > false", Boolean.compare(true, false) > 0);
    assertEquals(0, Boolean.compare(true, true));
  }

  public void testCtor() {
    assertTrue(new Boolean(btrue));
    assertTrue(new Boolean(true1));
    assertTrue(new Boolean(true2));
    assertTrue(new Boolean(true3));
    assertFalse(new Boolean(bfalse));
    assertFalse(new Boolean(false1));
    assertFalse(new Boolean(false2));
    assertFalse(new Boolean(false3));
    assertFalse(new Boolean(false4));
  }

  public void testParseBoolean() {
    assertTrue(Boolean.parseBoolean(true1));
    assertTrue(Boolean.parseBoolean(true2));
    assertTrue(Boolean.parseBoolean(true3));
    assertFalse(Boolean.parseBoolean(false1));
    assertFalse(Boolean.parseBoolean(false2));
    assertFalse(Boolean.parseBoolean(false3));
    assertFalse(Boolean.parseBoolean(false4));
  }

  public void testValueOf() {
    assertTrue(Boolean.valueOf(btrue));
    assertSame(Boolean.valueOf(btrue), Boolean.valueOf(btrue));
    assertTrue(Boolean.valueOf(true1));
    assertSame(Boolean.valueOf(true1), Boolean.valueOf(true1));
    assertTrue(Boolean.valueOf(true2));
    assertTrue(Boolean.valueOf(true3));
    assertFalse(Boolean.valueOf(bfalse));
    assertSame(Boolean.valueOf(bfalse), Boolean.valueOf(bfalse));
    assertFalse(Boolean.valueOf(false1));
    assertSame(Boolean.valueOf(false1), Boolean.valueOf(false1));
    assertFalse(Boolean.valueOf(false2));
    assertFalse(Boolean.valueOf(false3));
    assertFalse(Boolean.valueOf(false4));
  }

  public void testConstants() {
    assertSame(Boolean.FALSE, Boolean.FALSE);
    assertSame(Boolean.TRUE, Boolean.TRUE);
  }

  public static void testNPE() {
    if (isWasm()) {
      // TODO(b/183769034): Re-enable when NPE on dereference is supported
      return;
    }
    Boolean b = Math.random() < 0 ? Boolean.TRUE : null;
    try {
      assertEquals(null, b.booleanValue());
      fail("Should have thrown exception");
    } catch (Exception e) {
    }

    try {
      boolean bb = b;
      fail("Should have thrown exception" + bb);
    } catch (Exception e) {
    }
  }

  public void testEqualityNormalizer() {
    Boolean b = false;
    if (b != null) {
      assertEquals(false, b.booleanValue());
    } else {
      fail("false should not evaluate to null");
    }
    Object s = "";
    assertTrue(b != s);

    Object d = 0.0;
    assertTrue(b != d);
  }
}
